package com.yitao.cms.controller.order;


import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.skipper.base.bean.CommonStatus;
import com.skipper.base.bean.DataOutput;
import com.skipper.base.bean.PagedInput;
import com.skipper.base.bean.PagedOutput;
import com.skipper.base.utils.HttpUtils;
import com.yitao.client.constant.DesUtils;
import com.yitao.client.constant.OrderStatusEmnu;
import com.yitao.client.dto.pay.PayStreamDto;
import com.yitao.client.model.expressage.ServicesCompanyInfoModel;
import com.yitao.client.model.order.MallOrderDetailModel;
import com.yitao.cms.config.aopLog.LogAnnotation;
import com.yitao.cms.constant.UserErrorEnum;
import com.yitao.cms.constant.UserSession;
import com.yitao.cms.constant.order.LogisticsKeywordConstant;
import com.yitao.cms.constant.order.OrderEnums;
import com.yitao.cms.model.operationUser.OperationUserCmsModel;
import com.yitao.cms.service.constant.ConstantDataService;
import com.yitao.cms.service.order.CmsMallOrderRefundService;
import com.yitao.cms.service.order.CmsOrderDetailService;
import com.yitao.cms.service.order.CmsOrderService;
import com.yitao.cms.service.order.CmsServicesCompanyInfoService;
import com.yitao.cms.utils.BaseUtils;
import com.yitao.cms.utils.NumberUtil;
import com.yitao.cms.vo.CategoryVo;
import com.yitao.cms.vo.LogisticsInformationVo;
import com.yitao.cms.vo.order.CmsMallOrderDetailsInfoVo;
import com.yitao.cms.vo.order.CmsMallOrderVo;
import com.yitao.cms.vo.order.CmsOrderApplyRefundVo;
import com.yitao.cms.vo.order.OrderLogisticsList;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


@RestController
@RequestMapping(value = "/cms/order", produces = {"application/json"})
@Api(description = "运营后台订单相关接口", tags = {"cms-order"})
public class CmsOrderController {

    private BaseUtils base = BaseUtils.getInstance();

    @Autowired
    private CmsOrderService orderService;

    @Autowired
    private CmsOrderDetailService cmsOrderDetailService;

    @Autowired
    private CmsMallOrderRefundService cmsMallOrderRefundService;

    @Autowired
    private CmsServicesCompanyInfoService cmsServicesCompanyInfoService;

    @Autowired
    private ConstantDataService constantDataService;


    @ApiOperation("订单枚举列表")
    @RequestMapping(value = "/orderNumberCategory", method = RequestMethod.POST)
    public DataOutput<List<CategoryVo>> getOrderStatusNumber(
            @ApiParam(value = "订单列表枚举ID") @RequestParam(value = "searchEnum", required = false) Integer searchEnum,
            @ApiParam(value = "订单号") @RequestParam(value = "orderNo", required = false) String orderNo,
            @ApiParam(value = "支付类型") @RequestParam(value = "payType", required = false) Integer payType,
            @ApiParam(value = "开始时间") @RequestParam(value = "staDate", required = false) String staDate,
            @ApiParam(value = "结束时间") @RequestParam(value = "endDate", required = false) String endDate) {
        return orderService.getOrderCountByStatus(orderNo, searchEnum, staDate, endDate, payType);
    }

    @ApiOperation("订单列表")
    @RequestMapping(value = "/list", method = RequestMethod.POST)
    public PagedOutput<CmsMallOrderVo> getOrderListByOrderStatus(
            @ApiParam(value = "订单列表枚举ID") @RequestParam(value = "searchEnum", required = false) Integer searchEnum,
            @ApiParam(value = "订单号") @RequestParam(value = "orderNo", required = false) String orderNo,
            @ApiParam(value = "开始时间") @RequestParam(value = "staDate", required = false) String staDate,
            @ApiParam(value = "订单状态") @RequestParam(value = "orderStatus", required = false) Integer orderStatus,
            @ApiParam(value = "支付类型") @RequestParam(value = "payType", required = false) Integer payType,
            @ApiParam(value = "结束时间") @RequestParam(value = "endDate", required = false) String endDate,
            @ApiParam(value = "分页参数，表示当前页", required = true, defaultValue = "1") @RequestParam(value = "pageNo") Integer pageNo,
            @ApiParam(value = "分页参数，表示每页显示多少条记录", required = true, defaultValue = "10") @RequestParam(value = "pageSize") Integer pageSize) {
        if (orderStatus == null) {
            orderStatus = OrderStatusEmnu.CmsOrderShowStatusEnum.WAIT_DELIVER.getCode();
        }
        return orderService.getOrderListByBean(new PagedInput(pageSize, pageNo), orderNo, searchEnum, staDate, endDate, orderStatus, payType);
    }


    @ApiOperation("获取订单列表搜索枚举列表")
    @RequestMapping(value = "/getOrderListSearchEnum", method = RequestMethod.POST)
    public DataOutput<List<CategoryVo>> getOrderListSearchEnum() {
        OrderEnums.OrderListSearchEnum[] values = OrderEnums.OrderListSearchEnum.values();
        List<CategoryVo> categoryVoList = Lists.newArrayList();
        CategoryVo categoryVo = null;
        for (OrderEnums.OrderListSearchEnum orderListSearchEnum : values) {
            categoryVo = new CategoryVo();
            categoryVo.setKey(orderListSearchEnum.getCode());
            categoryVo.setValue(orderListSearchEnum.getName());
            categoryVoList.add(categoryVo);
        }
        return base.getSuccessMsg(categoryVoList);
    }


    //取消订单
    @ApiOperation("取消订单")
    @LogAnnotation(targetType = "cancel", remark = "取消订单")
    @RequestMapping(value = "/cancel", method = RequestMethod.POST)
    public DataOutput updtaeOrderStatusByCancel(@ApiParam(value = "订单id") @RequestParam(value = "orderId", required = false) Long orderId, HttpServletRequest request) {
        if (orderId == null) {
            return base.getErrorMsg();
        }
        return orderService.orderCancel(orderId, request);
    }

    /**
     * 订单改价
     */
    @ApiOperation("订单价格修改")
    @LogAnnotation(targetType = "alterPrice", remark = "订单价格修改")
    @RequestMapping(value = "/alter/price", method = RequestMethod.POST)
    public DataOutput updateOrderMoneyByOrderId(@ApiParam(value = "订单商品详情ID") @RequestParam(value = "orderDetailId", required = false) Long orderDetailId,
                                                @ApiParam(value = "订单价格(传入分单位)") @RequestParam(value = "price", required = false) Long price) {
        if (orderDetailId == null || price == null) {
            return base.getErrorMsg();
        }
        if (price <= 0L) {
            return base.getErrorMsg("输入有误 输入金额为" + price);
        }
        return orderService.updateOrderMoneyByOrderId(orderDetailId, price);
    }

    @ApiOperation("添加修改备注")
    @LogAnnotation(targetType = "remark", remark = "添加修改备注")
    @RequestMapping(value = "/remark", method = RequestMethod.POST)
    public DataOutput addRemark(@ApiParam(value = "订单id") @RequestParam(value = "orderId", required = false) Long orderId,
                                @ApiParam(value = "备注信息") @RequestParam(value = "remark", required = false) String remark) {
        if (orderId == null) {
            return base.getErrorMsg();
        }
        if (remark != null && remark.length() > 200) {
            return base.getErrorMsg("超出字段限制");
        }
        return orderService.addRemark(orderId, remark);
    }


    @ApiOperation("获取备注")
    @RequestMapping(value = "/get/remark", method = RequestMethod.POST)
    public DataOutput getRemark(@ApiParam(value = "订单id") @RequestParam(value = "orderId", required = false) Long orderId) {
        if (orderId == null) {
            return base.getErrorMsg();
        }
        return orderService.getRemark(orderId);
    }

    //发货订单
    @ApiOperation("发货订单")
    @RequestMapping(value = "/deliver", method = RequestMethod.POST)
    public DataOutput updtaeOrderStatusByDeliver(
            @ApiParam(value = "订单id") @RequestParam(value = "orderId", required = false) Long orderId,
            @ApiParam(value = "运单号") @RequestParam(value = "expressNumber", required = false) String expressNumber,
            @ApiParam(value = "快递公司名称") @RequestParam(value = "expressCode", required = false) Integer expressCode,
            HttpServletRequest request) {
        if (orderId == null) {
            return base.getErrorMsg();
        }
        OperationUserCmsModel userSession = UserSession.getUserSession(request);
        if (StringUtils.isEmpty(expressNumber)) {
            if (userSession.getShopId() == null) {
                return base.getErrorMsg();
            }
            if (!constantDataService.getTongtexpress(userSession.getShopId())) {
                return base.getErrorMsg("请填写物流单号");
            }
            String tongteExpressNumber = orderService.getTongteExpressNumber(orderId);
            if (StringUtils.isEmpty(tongteExpressNumber)) {
                return base.getErrorMsg("未获取到通特物流单号请稍后重试");
            }
            expressNumber = tongteExpressNumber;
            ServicesCompanyInfoModel tongte = cmsServicesCompanyInfoService.getServicesCompanyInfoByNameabbr("tongte");
            if (tongte == null) {
                return base.getErrorMsg("未查询到美国通特快递信息  请确认");
            }
            expressCode = Integer.valueOf(tongte.getId().toString());
        }
        return orderService.orderDeliver(orderId, expressNumber, expressCode, request, null);
    }

    //订单详情
    @ApiOperation("订单详情")
    @RequestMapping(value = "/details", method = RequestMethod.POST)
    public DataOutput<CmsMallOrderDetailsInfoVo> getOrderDetails(@ApiParam(value = "订单id") @RequestParam(value = "orderId", required = false) Long orderId, HttpServletRequest request) {
        if (orderId == null) {
            return base.getErrorMsg();
        }
        return orderService.getOrderInfoByOrderId(orderId);
    }

    /**
     * 查询物流信息
     */
    @ApiOperation("查询物流信息")
    @RequestMapping(value = "/logistics", method = RequestMethod.POST)
    public DataOutput<List<LogisticsInformationVo>> getKuaiDiMessageList(@ApiParam(value = "物流公司代号") @RequestParam(value = "deliveryCompanyCode", required = false) String deliveryCompanyCode,
                                                                         @ApiParam(value = "物流单号名称") @RequestParam(value = "deliveryNo", required = false) String deliveryNo,
                                                                         @ApiParam(value = "订单id") @RequestParam(value = "orderId", required = false) Long orderId, HttpServletRequest request) {
        return base.getSuccessMsg(orderService.getKuaiDiMessageList(deliveryCompanyCode, deliveryNo, orderId));
    }

    /**
     * 物流公司下拉
     */
    @ApiOperation("物流公司下拉")
    @RequestMapping(value = "/expressCode", method = RequestMethod.POST)
    public DataOutput<List<LogisticsInformationVo>> getExpressCodeo() {
        List<CategoryVo> categoryVoList = Lists.newArrayList();
        List<ServicesCompanyInfoModel> servicesCompanyInfoModelList = cmsServicesCompanyInfoService.getServicesCompanyInfoModelList();
        LogisticsKeywordConstant.ExpressCodeEnum[] values = LogisticsKeywordConstant.ExpressCodeEnum.values();
        for (ServicesCompanyInfoModel index : servicesCompanyInfoModelList) {
            CategoryVo categoryVo = new CategoryVo();
            categoryVo.setValue(index.getCompanyName());
            categoryVo.setKey(Integer.valueOf(index.getId().toString()));
            categoryVoList.add(categoryVo);
        }

        return base.getSuccessMsg(categoryVoList);
    }

    /**
     * 订单导出
     */

    @ApiOperation("订单导出")
    @RequestMapping(value = "/list/export", method = RequestMethod.GET)
    public void getOrderExport(
            HttpServletRequest request, HttpServletResponse response,
            @ApiParam(value = "订单号") @RequestParam(value = "orderNo", required = false) String orderNo,
            @ApiParam(value = "开始时间") @RequestParam(value = "staDate", required = false) String staDate,
            @ApiParam(value = "订单状态") @RequestParam(value = "orderStatus", required = false) Integer orderStatus,
            @ApiParam(value = "结束时间") @RequestParam(value = "endDate", required = false) String endDate) {
        orderService.getOrderExport(orderStatus, staDate, endDate, request, response);
        Map<String, String> map = Maps.newHashMap();
        map.put("url", request.getRequestURL().toString());
    }

    @ApiOperation("订单导入")
    @RequestMapping(value = "/list/impor", method = RequestMethod.POST)
    public DataOutput getOrderImpor(@ApiParam(value = "Excel文件", required = true)
                                    @RequestParam(value = "file") MultipartFile file, HttpServletRequest request) {
        //获取登录信息
        OperationUserCmsModel userSession = UserSession.getUserSession(request);
        if (userSession == null) {
            return new DataOutput(UserErrorEnum.NULL_LOGIN.getCode(), UserErrorEnum.NULL_LOGIN.getDesc());
        }

        Long exportId = 0L;
        String constantDataModelById = constantDataService.getConstantDataModelById(400L);//九洲
        String[] split = constantDataModelById.split(",");
        List<String> shopIds = Arrays.asList(split);
        String constantDataModelById1 = constantDataService.getConstantDataModelById(401L);//锦程
        String[] split1 = constantDataModelById1.split(",");
        List<String> shopIds1 = Arrays.asList(split1);
        if (shopIds != null && shopIds.contains(userSession.getShopId().toString())) {
            exportId = 400L;
        } else if (shopIds1 != null && shopIds1.contains(userSession.getShopId().toString())) {
            exportId = 401L;
        } else {
            return base.getErrorMsg("当前店铺不支持导入功能");
        }

        if (400L == exportId) {
            return orderService.getOrderImporJiuZhou(file, userSession, request);
        } else {
            return orderService.getOrderImporByJinCheng(file, userSession, request);
        }
        // Map<String, String> map = Maps.newHashMap();
        //  map.put("url", request.getRequestURL().toString());
    }

    /**
     * 查询售后订单列表
     */
    @ApiOperation("查询售后订单列表")
    @RequestMapping(value = "/afterSale", method = RequestMethod.POST)
    public PagedOutput<CmsMallOrderVo> getAfterSaleOrderList(@ApiParam(value = "搜索内容") @RequestParam(value = "orderNo", required = false) String orderNo,
                                                             @ApiParam(value = "搜索类型 1:商品名 2:收件人姓名 3:收件人手机 4:订单号") @RequestParam(value = "searchType", required = false) Integer searchType,
                                                             @ApiParam(value = "退款类型 0:全部 -10:申请退款中 -20:退款中 -30:已退款 -40:退款失败", required = true) @RequestParam(value = "refundStatus") Integer refundStatus,
                                                             @ApiParam(value = "支付类型") @RequestParam(value = "payType", required = false) Integer payType,
                                                             @ApiParam(value = "开始时间") @RequestParam(value = "staDate", required = false) String staDate,
                                                             @ApiParam(value = "结束时间") @RequestParam(value = "endDate", required = false) String endDate,
                                                             @ApiParam(value = "分页参数，表示当前页", required = true, defaultValue = "1") @RequestParam(value = "pageNo") Integer pageNo,
                                                             @ApiParam(value = "分页参数，表示每页显示多少条记录", required = true, defaultValue = "10") @RequestParam(value = "pageSize") Integer pageSize) {
        if (StringUtils.isEmpty(staDate)) {
            staDate = null;
        }
        if (StringUtils.isEmpty(endDate)) {
            endDate = null;
        }
        return cmsMallOrderRefundService.getRefundOrderList(new PagedInput(pageSize, pageNo), orderNo, searchType, refundStatus, staDate, endDate, payType);
    }


    /**
     * 售后订单详情
     */
    @ApiOperation("获取支付方式")
    @RequestMapping(value = "/getPayType", method = RequestMethod.POST)
    public DataOutput getPayType() {
        return orderService.getPayType();
    }


    /**
     * 售后订单详情
     */
    @ApiOperation("售后订单详情")
    @RequestMapping(value = "/afterSale/info", method = RequestMethod.POST)
    public DataOutput<CmsMallOrderDetailsInfoVo> getAfterSaleOrderInfo(@ApiParam(value = "售后ID ") @RequestParam(value = "afterSaleId", required = false) Long afterSaleId) {
        return cmsMallOrderRefundService.getAfterSaleOrderInfo(afterSaleId);
    }

    /**
     * 售后订单售后状态枚举
     */
    @ApiOperation("售后订单售后状态枚举")
    @RequestMapping(value = "/afterSale/status", method = RequestMethod.POST)
    public DataOutput<CategoryVo> getAfterSaleOrderStatus(@ApiParam(value = "售后ID ") @RequestParam(value = "afterSaleId", required = false) Long afterSaleId) {

        return orderService.getAfterSaleOrderStatus(afterSaleId);
    }

    @Value("${refund_url}")
    private String refundUrl;

    /**
     * 售后订单详情
     */
    @ApiOperation("解决售后订单")
    @RequestMapping(value = "/afterSale/solve", method = RequestMethod.POST)
    public DataOutput updateAfterSaleOrderSolve(@ApiParam(value = "售后ID ") @RequestParam(value = "afterSaleId", required = false) Long orderId,
                                                @ApiParam(value = "金额 ") @RequestParam(value = "amount", required = false) Double amount,
                                                @ApiParam(value = "退款状态 ") @RequestParam(value = "solveStatus", required = false) Integer solveStatus) {

        Long amountLong = NumberUtil.yuanToCent(amount);
        DataOutput<PayStreamDto> payStreamModel = cmsMallOrderRefundService.updateAfterSaleOrderSolve(orderId, amountLong, solveStatus);
        if (payStreamModel != null && payStreamModel.getData() != null && payStreamModel.getStatus().equals(CommonStatus.SUCCESS.getCode())) {
            PayStreamDto data = payStreamModel.getData();
            if (solveStatus.equals(OrderEnums.RefundStatusEnums.CANCELED.getCode())) {
                solveStatus = -15;
            } else if (solveStatus.equals(OrderEnums.RefundStatusEnums.OFFLINE_REFUND.getCode())) {
                return payStreamModel;
            } else {
                if (payStreamModel != null) {
                    Map<String, String> map = Maps.newConcurrentMap();
                    if (amount == null) {
                        amountLong = data.getPayCashFee();
                    }
                    map.put("orderId", DesUtils.encryptDES(data.getOrderId().toString()));
                    map.put("payType", DesUtils.encryptDES(data.getPayClientType().toString()));
                    map.put("amount", DesUtils.encryptDES(amountLong.toString()));
                    String post = HttpUtils.post(refundUrl, map);
                    System.out.println("返回信息" + post);
                }
            }
        } else {
            return payStreamModel;
        }
        return base.getSuccessMsg();
    }

    @ApiOperation("缺货标记")
    @LogAnnotation(targetType = "stockout", remark = "缺货标记")
    @RequestMapping(value = "/stockout", method = RequestMethod.POST)
    public DataOutput stockoutTab(@ApiParam(value = "商品详情ID") @RequestParam(value = "orderDetailId", required = false) Long orderDetailId,
                                  @ApiParam(value = "商品数量") @RequestParam(value = "quantity", required = false) Integer quantity) {

        return orderService.stockoutTab(orderDetailId, quantity);
    }

    //商品发货
    @ApiOperation("商品发货")
    @LogAnnotation(targetType = "goodsDelivery", remark = "商品发货")
    @RequestMapping(value = "/goods/delivery", method = RequestMethod.POST)
    public DataOutput partOfTheShipment(@ApiParam(value = "商品详情ID") @RequestParam(value = "orderDetailId", required = false) Long orderDetailId,
                                        @ApiParam(value = "运单号") @RequestParam(value = "expressNumber", required = false) String expressNumber,
                                        @ApiParam(value = "快递公司名称") @RequestParam(value = "expressCode", required = false) Integer expressCode,
                                        HttpServletRequest request) {

        if (orderDetailId == null) {
            return base.getErrorMsg("请选择发货的商品");
        }
        OperationUserCmsModel userSession = UserSession.getUserSession(request);


        if (StringUtils.isEmpty(expressNumber)) {
            if (userSession.getShopId() == null) {
                return base.getErrorMsg();
            }
            if (!constantDataService.getTongtexpress(userSession.getShopId())) {
                return base.getErrorMsg("请填写物流单号");
            }
            MallOrderDetailModel mallOrderDetailModelById = cmsOrderDetailService.getMallOrderDetailModelById(orderDetailId);
            String tongteExpressNumber = orderService.getTongteExpressNumber(mallOrderDetailModelById.getOrderId());
            if (StringUtils.isEmpty(tongteExpressNumber)) {
                return base.getErrorMsg("未获取到通特物流单号请稍后重试");
            }
            expressNumber = tongteExpressNumber;
            ServicesCompanyInfoModel tongte = cmsServicesCompanyInfoService.getServicesCompanyInfoByNameabbr("tongte");
            if (tongte == null) {
                return base.getErrorMsg("未查询到美国通特快递信息  请确认");
            }
            expressCode = Integer.valueOf(tongte.getId().toString());
        }
        if (expressCode == null) {
            return base.getErrorMsg("请选择快递公司");
        }
        return orderService.partOfTheShipment(orderDetailId, expressNumber, expressCode, request, null);
    }

    @ApiOperation("获取退款枚举状态")
    @RequestMapping(value = "/refundEnum", method = RequestMethod.POST)
    public DataOutput<List<Map<String, Object>>> getRefundEnum() {
        return new DataOutput(OrderEnums.REFUND_STATUS.getRefundEnum());
    }

    @ApiOperation("获取退款搜索枚举列表")
    @RequestMapping(value = "/getRefundSearchEnum", method = RequestMethod.POST)
    public DataOutput<List<Map<String, Object>>> getRefundSearchEnum() {
        return new DataOutput(OrderEnums.REFUND_SEARCH_ENUM.getRefundSearchEnum());
    }


    @ApiOperation("获取订单对账列表")
    @RequestMapping(value = "/getOrderStreamList", method = RequestMethod.GET)
    public void getOrderStreamList(@ApiParam(value = "店铺id") @RequestParam(value = "shopId", required = false) Long shopId,
                                   @ApiParam(value = "payType,1汇付，2联动") @RequestParam(value = "payType", required = true) Integer payType,
                                   @ApiParam(value = "orderStatus，1退款，2交易成功 全部则不传 ") @RequestParam(value = "orderStatus", required = false) Integer orderStatus,
                                   @ApiParam(value = "开始时间") @RequestParam(value = "staDate", required = true) String staDate,
                                   @ApiParam(value = "结束时间") @RequestParam(value = "endDate", required = true) String endDate,
                                   HttpServletRequest request, HttpServletResponse response) {
        orderService.getOrderStreamList(shopId, payType, orderStatus, staDate, endDate, request, response);
    }


    /**
     * 发起退款
     */
    @ApiOperation("发起退款")
    @LogAnnotation(targetType = "applyRefund", remark = "发起退款")
    @RequestMapping(value = "/applyRefund", method = RequestMethod.POST)
    public DataOutput applyRefund(@RequestBody CmsOrderApplyRefundVo cmsOrderApplyRefundVo) {
        return orderService.applyRefund(cmsOrderApplyRefundVo);
    }


    /**
     * 查询包裹
     */

    //查询包裹
    @ApiOperation("查询包裹")
    @RequestMapping(value = "/packageList", method = RequestMethod.POST)
    public DataOutput<List<OrderLogisticsList>> getPackageList(@ApiParam(value = "订单id") @RequestParam(value = "orderId", required = false) Long orderId, HttpServletRequest request) {
        if (orderId == null) {
            return base.getErrorMsg();
        }
        return orderService.getPackageList(orderId);
    }

    /**
     * 修改物流单号
     */

    @ApiOperation("修改物流单号")
    @RequestMapping(value = "/updateDeliveryNo", method = RequestMethod.POST)
    public DataOutput updateDeliveryNo(
            @ApiParam(value = "订单id") @RequestParam(value = "deliveryId", required = false) Long deliveryId,
            @ApiParam(value = "运单号") @RequestParam(value = "expressNumber", required = false) String expressNumber,
            @ApiParam(value = "快递公司code") @RequestParam(value = "expressCode", required = false) Integer expressCode,
            HttpServletRequest request) {
        return orderService.updateDeliveryNo(deliveryId, expressNumber, expressCode);
    }
}
